import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useUserStore } from '@/stores/user'
import { getToken } from './auth'

// 创建axios实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 15 * 1000,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 添加认证token
    const token = getToken()
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    
    // 确保URL格式正确
    // if (config.url && !config.url.startsWith('/api/')) {
    //   config.url = '/api' + (config.url.startsWith('/') ? config.url : '/' + config.url)
    // }
    
    // 添加时间戳防止缓存
    if (config.method === 'get') {
      config.params = {
        ...config.params,
        _t: Date.now()
      }
    }
    
    return config
  },
  (error) => {
    console.error('请求错误:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const { data, status } = response
    
    
    // 如果是文件下载
    if (response.config.responseType === 'blob') {
      return response
    }

    
    // 成功响应
    if (status === 200) {
      return data
    }

    
    // 其他状态码
    ElMessage.error(data.message || '请求失败')
    return Promise.reject(new Error(data.message || '请求失败'))
  },
  async (error) => {
    const { response } = error
    
    
    if (response) {
      const { status, data } = response
      
      switch (status) {
        case 401:
          // 未授权，清除token并跳转登录页
          const userStore = useUserStore()
          
          if (data.code === 'TOKEN_EXPIRED') {
            userStore.logout()
          } else {
            ElMessage.error('认证失败，请重新登录')
            userStore.logout()
          }
          break
          
        case 403:
          ElMessage.error('权限不足，无法访问')
          break
          
        case 404:
          ElMessage.error('请求的资源不存在')
          break
          
        case 422:
          // 表单验证错误
          if (data.errors) {
            const errorMessages = Object.values(data.errors).flat()
            ElMessage.error(errorMessages[0] as string)
          } else {
            ElMessage.error(data.message || '请求参数错误')
          }
          break
          
        case 429:
          ElMessage.error('请求过于频繁，请稍后再试')
          break
          
        case 500:
          ElMessage.error('服务器内部错误')
          break
          
        case 502:
        case 503:
        case 504:
          ElMessage.error('服务暂时不可用，请稍后再试')
          break
          
        default:
          ElMessage.error(data.message || `请求失败 (${status})`)
      }
    } else if (error.code === 'ECONNABORTED') {
      ElMessage.error('请求超时，请检查网络连接')
    } else if (error.message.includes('Network Error')) {
      ElMessage.error('网络连接失败，请检查网络')
    } else {
      ElMessage.error('请求失败，请稍后重试')
    }
    
    return Promise.reject(error)
  }
)

// 请求方法封装
interface RequestOptions extends AxiosRequestConfig {
  showLoading?: boolean
  showError?: boolean
}

class Request {
  private static instance: Request
  
  static getInstance(): Request {
    if (!Request.instance) {
      Request.instance = new Request()
    }
    return Request.instance
  }
  
  // GET请求
  get<T = any>(url: string, params?: any, options?: RequestOptions): Promise<T> {
    return service.get(url, { params, ...options })
  }
  
  // POST请求
  post<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return service.post(url, data, options)
  }
  
  // PUT请求
  put<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return service.put(url, data, options)
  }
  
  // DELETE请求
  delete<T = any>(url: string, params?: any, options?: RequestOptions): Promise<T> {
    return service.delete(url, { params, ...options })
  }
  
  // PATCH请求
  patch<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return service.patch(url, data, options)
  }
  
  // 文件上传
  upload<T = any>(url: string, formData: FormData, options?: RequestOptions): Promise<T> {
    return service.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      ...options
    })
  }
  
  // 文件下载
  download(url: string, params?: any, filename?: string): Promise<void> {
    return service.get(url, {
      params,
      responseType: 'blob'
    }).then((response) => {
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    })
  }
}

const request = Request.getInstance()

export default request
export { service }